home *** CD-ROM | disk | FTP | other *** search
/ Aminet 28 / Aminet 28 (1998)(GTI - Schatztruhe)[!][Dec 1998].iso / Aminet / dev / c / qtools0.2-src.lha / src / libqdisplay / clippoly.c < prev    next >
Encoding:
C/C++ Source or Header  |  1998-07-10  |  3.2 KB  |  129 lines

  1. #define    LIBQDISPLAY_CORE
  2. #include "../include/libqdisplay.h"
  3.  
  4. /* CLIPPOLY.c - LOTS OF WORK TO DO :) */
  5.  
  6. static point_3d clipPoints[16], *clipList1[40], *clipList2[40];
  7.  
  8. #define X p[0]
  9. #define Y p[1]
  10. #define Z p[2]
  11.  
  12. static void intersect(point_3d * out, point_3d * a, point_3d * b, float where)
  13. {
  14.   /* intersection occurs 'where' % along the line from a to b */
  15.   out->X = a->X + (b->X - a->X) * where;
  16.   out->Y = a->Y + (b->Y - a->Y) * where;
  17.   out->Z = a->Z + (b->Z - a->Z) * where;
  18.  
  19.   transform_rotated_point(out);
  20. }
  21.  
  22. /* compute 'where' for various clip planes */
  23. static float left_loc(point_3d * a, point_3d * b)
  24. {
  25.   return -(a->Z + a->X * clipScaleX) / ((b->X - a->X) * clipScaleX + b->Z - a->Z);
  26. }
  27.  
  28. static float right_loc(point_3d * a, point_3d * b)
  29. {
  30.   return (a->Z - a->X * clipScaleX) / ((b->X - a->X) * clipScaleX - b->Z + a->Z);
  31. }
  32.  
  33. static float top_loc(point_3d * a, point_3d * b)
  34. {
  35.   return (a->Z - a->Y * clipScaleY) / ((b->Y - a->Y) * clipScaleY - b->Z + a->Z);
  36. }
  37.  
  38. static float bottom_loc(point_3d * a, point_3d * b)
  39. {
  40.   return -(a->Z + a->Y * clipScaleY) / ((b->Y - a->Y) * clipScaleY + b->Z - a->Z);
  41. }
  42.  
  43. /* clip the polygon to each of the view frustrum planes */
  44. int clip_poly(int n, point_3d ** vl, int codes_or, point_3d *** out_vl)
  45. {
  46.   int i, j, k, p = 0;                        /* p = index into temporary point pool */
  47.  
  48.   point_3d **cur;
  49.  
  50.   if (codes_or & CC_OFF_LEFT) {
  51.     cur = clipList1;
  52.     k = 0;
  53.     j = n - 1;
  54.     for (i = 0; i < n; ++i) {
  55.       /*
  56.        * process edge from j..i
  57.        * if j is inside, add it
  58.        */
  59.       if (!(vl[j]->ccodes & CC_OFF_LEFT))
  60.     cur[k++] = vl[j];
  61.       /* if it crosses, add the intersection point */
  62.       if ((vl[j]->ccodes ^ vl[i]->ccodes) & CC_OFF_LEFT) {
  63.     intersect(&clipPoints[p], vl[i], vl[j], left_loc(vl[i], vl[j]));
  64.     cur[k++] = &clipPoints[p++];
  65.       }
  66.       j = i;
  67.     }
  68.     /* move output list to be input */
  69.     n = k;
  70.     vl = cur;
  71.   }
  72.  
  73.   if (codes_or & CC_OFF_RIGHT) {
  74.     cur = (vl == clipList1) ? clipList2 : clipList1;
  75.     k = 0;
  76.     j = n - 1;
  77.     for (i = 0; i < n; ++i) {
  78.       if (!(vl[j]->ccodes & CC_OFF_RIGHT))
  79.     cur[k++] = vl[j];
  80.       if ((vl[j]->ccodes ^ vl[i]->ccodes) & CC_OFF_RIGHT) {
  81.     intersect(&clipPoints[p], vl[i], vl[j], right_loc(vl[i], vl[j]));
  82.     cur[k++] = &clipPoints[p++];
  83.       }
  84.       j = i;
  85.     }
  86.     n = k;
  87.     vl = cur;
  88.   }
  89.   if (codes_or & CC_OFF_TOP) {
  90.     cur = (vl == clipList1) ? clipList2 : clipList1;
  91.     k = 0;
  92.     j = n - 1;
  93.     for (i = 0; i < n; ++i) {
  94.       if (!(vl[j]->ccodes & CC_OFF_TOP))
  95.     cur[k++] = vl[j];
  96.       if ((vl[j]->ccodes ^ vl[i]->ccodes) & CC_OFF_TOP) {
  97.     intersect(&clipPoints[p], vl[i], vl[j], top_loc(vl[i], vl[j]));
  98.     cur[k++] = &clipPoints[p++];
  99.       }
  100.       j = i;
  101.     }
  102.     n = k;
  103.     vl = cur;
  104.   }
  105.   if (codes_or & CC_OFF_BOT) {
  106.     cur = (vl == clipList1) ? clipList2 : clipList1;
  107.     k = 0;
  108.     j = n - 1;
  109.     for (i = 0; i < n; ++i) {
  110.       if (!(vl[j]->ccodes & CC_OFF_BOT))
  111.     cur[k++] = vl[j];
  112.       if ((vl[j]->ccodes ^ vl[i]->ccodes) & CC_OFF_BOT) {
  113.     intersect(&clipPoints[p], vl[i], vl[j], bottom_loc(vl[i], vl[j]));
  114.     cur[k++] = &clipPoints[p++];
  115.       }
  116.       j = i;
  117.     }
  118.     n = k;
  119.     vl = cur;
  120.   }
  121.  
  122.   for (i = 0; i < n; ++i)
  123.     if (vl[i]->ccodes & CC_BEHIND)
  124.       return 0;
  125.  
  126.   *out_vl = vl;
  127.   return n;
  128. }
  129.